package org.ragdollcat.first.manager.auth;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.Header;
import cn.hutool.json.JSONUtil;
import org.ragdollcat.first.model.entity.*;
import org.ragdollcat.first.model.enums.SpaceRoleEnum;
import org.ragdollcat.first.model.enums.SpaceTypeEnum;
import org.ragdollcat.first.service.SpaceUserService;
import org.ragdollcat.first.service.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
public class SpaceUserAuthManager {

    /**
     * 转化spaceUserAuthConfig.json为SpaceUserAuthConfig实例
     */
    private static final SpaceUserAuthConfig SPACE_USER_AUTH_CONFIG;

    /**
     * 从配置文件中读取上下文路径
     */
    @Value("${server.servlet.context-path}")
    private String context;

    @Resource
    private UserService userService;

    @Resource
    private SpaceUserService spaceUserService;

    /**
     * 类加载时进行读取并初始化
     */
    static {
        String configJson = ResourceUtil.readUtf8Str("biz/spaceUserAuthConfig.json");
        SPACE_USER_AUTH_CONFIG = JSONUtil.toBean(configJson, SpaceUserAuthConfig.class);
    }

    /**
     * 根据角色，获取其权限
     * 例如：
     * "picture:view",
     * "picture:upload",
     * "picture:edit",
     * "picture:delete"
     */
    public List<String> getPermessionsByRole(String spaceUserRole) {
        if (StrUtil.isBlank(spaceUserRole)) {
            return new ArrayList<>();
        }
        List<SpaceUserRole> spaceUserRoles = SPACE_USER_AUTH_CONFIG.getRoles();
        SpaceUserRole role = spaceUserRoles.stream().filter(spaceUser -> spaceUser.getKey().equals(spaceUserRole)).findFirst().orElse(null);
        if (ObjUtil.isEmpty(role)) {
            return new ArrayList<>();
        }
        return role.getPermissions();
    }

    /**
     * 根据请求获取对应的上下文
     *
     * @return
     */
    public SpaceUserAuthContext getAuthContextByRequest() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        //区分请求头的类型
        String contentType = request.getHeader(Header.CONTENT_TYPE.getValue());
        SpaceUserAuthContext spaceUserAuthContext = null;
        if (ContentType.JSON.getValue().equals(contentType)) {
            String body = ServletUtil.getBody(request);
            spaceUserAuthContext = JSONUtil.toBean(body, SpaceUserAuthContext.class);
        } else {
            Map<String, String> paramMap = ServletUtil.getParamMap(request);
            spaceUserAuthContext = BeanUtil.toBean(paramMap, SpaceUserAuthContext.class);
        }
        //根据请求路径区分ID的含义
        Long id = spaceUserAuthContext.getId();
        if (id != null) {
            String requestURI = request.getRequestURI();
            String pathUri = requestURI.replace(context + "/", "");
            String moduleName = StrUtil.subBefore(pathUri, "/", false);
            switch (moduleName) {
                case "picture":
                    spaceUserAuthContext.setPictureId(id);
                    break;
                case "space":
                    spaceUserAuthContext.setSpaceId(id);
                    break;
                case "spaceUser":
                    spaceUserAuthContext.setSpaceUserId(id);
                    break;
                default:
            }
        }
        return spaceUserAuthContext;
    }

    /**
     * 根据角色获取权限列表
     *
     * @param space
     * @param loginUser
     * @return
     */
    public List<String> getPermissionList(Space space, User loginUser) {
        if (loginUser == null) {
            return new ArrayList<>();
        }
        // 管理员权限
        List<String> ADMIN_PERMISSIONS = getPermessionsByRole(SpaceRoleEnum.ADMIN.getValue());
        // 公共图库
        if (space == null) {
            if (userService.isAdmin(loginUser)) {
                return ADMIN_PERMISSIONS;
            }
            return new ArrayList<>();
        }
        SpaceTypeEnum spaceTypeEnum = SpaceTypeEnum.getEnumByValue(space.getSpaceType());
        if (spaceTypeEnum == null) {
            return new ArrayList<>();
        }
        // 根据空间获取对应的权限
        switch (spaceTypeEnum) {
            case PRIVATE:
                // 私有空间，仅本人或管理员有所有权限
                if (space.getUserId().equals(loginUser.getId()) || userService.isAdmin(loginUser)) {
                    return ADMIN_PERMISSIONS;
                } else {
                    return new ArrayList<>();
                }
            case TEAM:
                // 团队空间，查询 SpaceUser 并获取角色和权限
                SpaceUser spaceUser = spaceUserService.lambdaQuery()
                        .eq(SpaceUser::getSpaceId, space.getId())
                        .eq(SpaceUser::getUserId, loginUser.getId())
                        .one();
                if (spaceUser == null) {
                    return new ArrayList<>();
                } else {
                    return getPermessionsByRole(spaceUser.getSpaceRole());
                }
        }
        return new ArrayList<>();
    }


}
